﻿//-----------------------------------------------------------------------
// <copyright file="AssertMany.cs" company="tuliprules.org">
//     Copyright (c) 2010 tuplelister, tuliprules.org.
// </copyright>
// <summary>This is the AssertMany class.</summary>
//-----------------------------------------------------------------------

namespace Tulip.Engine.EngineOperation
{
    using System.Diagnostics;
    using Tuples;

    /// <summary>
    /// Represents an 'assert many' engine operation.   Asserts a collection of facts to the engine.
    /// </summary>
    internal class AssertMany : EngineOperation<object[]>
    {
        /// <summary>
        /// Initializes a new instance of the AssertMany class.
        /// </summary>
        /// <param name="session">The current tuple store session.</param>
        /// <param name="facts">A collection of facts to be asserted.</param>
        public AssertMany(TupleStoreSession session, object[] facts)
        {
            Debug.Assert(facts != null, "Fact array containing facts to be asserted cannot be null");

            this.session = session;
            this.data = facts;
        }

        #region IEngineOperation Members

        /// <summary>
        /// Performs the engine operation.
        /// </summary>
        /// <param name="facts">Ignored in this implementation.</param>
        /// <returns>Indicates if the engine should start a new match-resolve-do cycle.</returns>
        public override bool Perform(ref object[] facts)
        {
            foreach (var fact in this.data)
            {
                var tupleList = new TupleMonadLinkedList();

                // Assert the fact and register an entity tuple
                this.session.Assert(fact);

                // Retrieve the entity tuple from the tupleStore and add to inner list
                tupleList.Add(this.GetEntityTuple(fact));

                // Lift the tuple list into the TupleList monad, and add the session for context
                var tupleListMonad = new TupleList(tupleList, this.session);

                // Add callback to EvaluateType
                tupleListMonad.AddMonadicFunction(this.session.InitialMonadicFunctions);

                // Start the execution of a computational sequence
                tupleListMonad.ExecuteSequence();
            }

            return false;
        }

        #endregion
    }
}
